package com.wm.practice;

import java.util.concurrent.*;

/**
 * @ClassName: CompletableFutureBuildDemo
 * @Description: CompletableFuture异步回调
 * @Author: Deamer
 * @Date: 2022/8/28 16:22
 **/
public class CompletableFutureBuildDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // pool-1-thread-1子进程come in
        // main主线程先去忙别的任务
        // 1秒后出结果
        // 计算完成，更新系统updateValue:4
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "子进程come in");
            int result = ThreadLocalRandom.current().nextInt(10);// 产生一个随机数
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("结果异常值判断:" + result);
            //---------------------异常情况的演示--------------------------------------
            if (result > 2) {
                int i = 10 / 0;//我们主动的给一个异常情况
            }
            //------------------------------------------------------------------
            return result;
        }, threadPool).whenComplete((v, e) -> {
            if (e == null) {
                System.out.println("计算完成，更新系统updateValue:" + v);
            }
        }).exceptionally(e -> {
            e.printStackTrace();
            System.out.println("异常情况" + e.getCause() + "\t" + e.getMessage());
            return null;
        });
        // 线程不要立刻结束，否则CompletableFuture默认使用的线程池会立刻关闭：暂停3秒钟线程
        System.out.println(Thread.currentThread().getName() + "主线程先去忙别的任务");
        TimeUnit.SECONDS.sleep(3);
    }

    private static void whenCompleteTest() throws InterruptedException {
        // ForkJoinPool.commonPool-worker-1线程come in（这里用的是默认的ForkJoinPool）
        // main线程先去忙其他任务
        // 1秒后出结果
        // 计算完成，更新系统updateValue:7
        CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "子进程come in");
            int result = ThreadLocalRandom.current().nextInt(10);// 产生一个随机数
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("1秒后出结果");
            return result;
        }).whenComplete((v, e) -> {// 没有异常，v是值，e是异常
            if (e == null) {
                System.out.println("计算完成，更新系统updateValue:" + v);
            }
        }).exceptionally(e -> {
            e.printStackTrace();
            System.out.println("异常情况" + e.getCause() + "\t" + e.getMessage());
            return null;
        });

        // 线程不要立刻结束，否则CompletableFuture默认使用的线程池会立刻关闭：暂停3秒钟线程
        System.out.println(Thread.currentThread().getName() + "主线程先去忙别的任务");
        TimeUnit.SECONDS.sleep(3);
    }

    private static void baseFuture() throws InterruptedException, ExecutionException {
        // main线程先去忙别的任务
        // ForkJoinPool.commonPool-worker-1子线程come in
        // 1秒钟后出结果2
        CompletableFuture<Object> objectCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "子进程come in");
            int result = ThreadLocalRandom.current().nextInt(10);// 产生一个随机数
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("1秒后出结果");
            return result;
        });
        System.out.println(Thread.currentThread().getName() + "主线程先去忙别的任务");
        System.out.println(objectCompletableFuture.get());
    }

    private static void supplyAsyncTest2() throws InterruptedException, ExecutionException {
        // 使用指定的线程池pool-1-thread-1
        // hello supplyAsync---有返回值
        ExecutorService executorService = Executors.newFixedThreadPool(3);// 加入线程池
        CompletableFuture<String> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            // 停顿几秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "hello supplyAsync";
        }, executorService);
        System.out.println(voidCompletableFuture.get());
    }

    private static void supplyAsyncTest() throws InterruptedException, ExecutionException {
        // 使用默认的线程池ForkJoinPool.commonPool-worker-1
        // hello supplyAsync---有返回值
        CompletableFuture<String> objectCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            // 停顿几秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "hello supplyAsync";
        });
        System.out.println(objectCompletableFuture.get());
    }

    private static void asyncTest2() throws InterruptedException, ExecutionException {
        // 使用指定的线程池pool-1-thread-1
        // null---没有返回值
        ExecutorService executorService = Executors.newFixedThreadPool(3);// 加入线程池
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            // 停顿几秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, executorService);
        System.out.println(voidCompletableFuture.get());
    }

    private static void asyncTest() throws InterruptedException, ExecutionException {
        // 使用默认线程池ForkJoinPool.commonPool-worker-1
        // null---没有返回值
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            // 停顿几秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(voidCompletableFuture.get());
    }
}
